package org.gdstash.db;

import org.gdstash.util.GDMsgFormatter;
import org.gdstash.util.GDMsgLogger;

import java.sql.*;
import java.util.LinkedList;
import java.util.List;

public class DBSkillBonusLevel {
    public static final String TABLE_NAME_ITEM = "GD_ITEM_SKILL_LEVEL";
    public static final String TABLE_NAME_ITEMSET = "GD_ITEMSET_SKILL_LEVEL";
    public static final String TABLE_NAME_AFFIX = "GD_AFFIX_SKILL_LEVEL";
    private static final String FIELD_ID_ITEM = "ITEM_ID";
    private static final String FIELD_ID_ITEMSET = "ITEMSET_ID";
    private static final String FIELD_ID_AFFIX = "AFFIX_ID";
    private static final int ROW_ITEM_ID = 1;
    private static final int ROW_BONUS_TYPE = 2;
    private static final int ROW_INDEX = 3;
    private static final int ROW_BONUS_LEVEL = 4;
    private static final int ROW_BONUS_VALUE = 5;
    private String itemID;
    private int type;
    private int index;
    private int bonusLevel;
    private int bonusValue;

    public DBSkillBonusLevel() {
        this.itemID = null;
    }

    public DBSkillBonusLevel(final int bonusValue, final int bonusLevel) {
        this.itemID = null;
        this.bonusLevel = bonusLevel;
        this.bonusValue = bonusValue;
    }

    public int getLevel() {
        return this.bonusLevel;
    }

    public int getValue() {
        return this.bonusValue;
    }

    public static void createTable(final Connection conn, final String tabName, final String idName) throws SQLException {
        final String dropTable = "DROP TABLE " + tabName;
        final String createTable = "CREATE TABLE " + tabName + " (" + idName + "    VARCHAR(" + "256" + ") NOT NULL, TYPE         INTEGER, INDEX        INTEGER, LEVEL        INTEGER, BONUS_VALUE  INTEGER, PRIMARY KEY (" + idName + ", TYPE, INDEX, LEVEL))";
        try (final Statement st = conn.createStatement()) {
            if (GDDBUtil.tableExists(conn, tabName)) {
                st.execute(dropTable);
            }
            st.execute(createTable);
            st.close();
            conn.commit();
        } catch (SQLException ex) {
            final Object[] args = {tabName};
            final String msg = GDMsgFormatter.format(GDMsgFormatter.rbMsg, "ERR_CREATE_TABLE", args);
            GDMsgLogger.addError(msg);
            throw ex;
        }
    }

    public static void delete(final Connection conn, final String tabName, final String idName, final String itemID) throws SQLException {
        final String deleteEntry = "DELETE FROM " + tabName + " WHERE " + idName + " = ?";
        try (final PreparedStatement ps = conn.prepareStatement(deleteEntry)) {
            ps.setString(1, itemID);
            ps.executeUpdate();
            ps.close();
        } catch (SQLException ex) {
            conn.rollback();
        }
    }

    public static void insert(final Connection conn, final String tabName, final String id, final DBSkillBonus bonus) throws SQLException {
        final String insert = "INSERT INTO " + tabName + " VALUES (?,?,?,?,?)";
        if (bonus.getLevelList() == null) {
            return;
        }
        if (bonus.getLevelList().isEmpty()) {
            return;
        }
        try (final PreparedStatement ps = conn.prepareStatement(insert)) {
            for (final DBSkillBonusLevel level : bonus.getLevelList()) {
                ps.setString(1, id);
                ps.setInt(2, bonus.getSkillBonusType());
                ps.setInt(3, bonus.getIndex());
                ps.setInt(4, level.bonusLevel);
                ps.setInt(5, level.bonusValue);
                ps.executeUpdate();
                ps.clearParameters();
            }
            ps.close();
        }
    }

    public static List<DBSkillBonusLevel> get(final String tableName, final String fieldName, final DBSkillBonus bonus) {
        List<DBSkillBonusLevel> list = new LinkedList<DBSkillBonusLevel>();
        final String command = "SELECT * FROM " + tableName + " WHERE " + fieldName + " = ? AND TYPE = ? AND INDEX = ?";
        try (final Connection conn = GDDBData.getConnection();
             final PreparedStatement ps = conn.prepareStatement(command)) {
            ps.setString(1, bonus.getID());
            ps.setInt(2, bonus.getSkillBonusType());
            ps.setInt(3, bonus.getIndex());
            try (final ResultSet rs = ps.executeQuery()) {
                list = wrap(rs);
                conn.commit();
            } catch (SQLException ex) {
                throw ex;
            }
        } catch (SQLException ex2) {
            final Object[] args = {bonus.getID(), tableName};
            final String msg = GDMsgFormatter.format(GDMsgFormatter.rbMsg, "ERR_READ_TABLE_BY_ID", args);
            GDMsgLogger.addError(msg);
            GDMsgLogger.addError(ex2);
        }
        return list;
    }

    private static List<DBSkillBonusLevel> wrap(final ResultSet rs) throws SQLException {
        final LinkedList<DBSkillBonusLevel> list = new LinkedList<DBSkillBonusLevel>();
        while (rs.next()) {
            final DBSkillBonusLevel level = new DBSkillBonusLevel();
            level.itemID = rs.getString(1);
            level.type = rs.getInt(2);
            level.index = rs.getInt(3);
            level.bonusLevel = rs.getInt(4);
            level.bonusValue = rs.getInt(5);
            list.add(level);
        }
        return list;
    }
}
